"""
RedFire框架统一配置系统

使用Pydantic BaseSettings替代手写ConfigManager，提供类型安全的配置管理。
支持环境变量、配置文件、默认值的多层级配置。
"""

try:
    from pydantic_settings import BaseSettings
except ImportError:
    from pydantic import BaseSettings
    
from pydantic import Field, validator
from typing import Optional, Dict, Any, List
from pathlib import Path
import os


class RedFireSettings(BaseSettings):
    """
    RedFire框架基础配置类
    
    所有微服务配置继承此基类，获得标准化的配置管理：
    - 环境变量自动映射
    - 类型验证和转换
    - 配置文件支持
    - 敏感信息保护
    
    ⚠️  重要变更：框架不再强制单一数据库配置
    每个服务应该定义自己的数据库配置类，继承 ServiceDatabaseConfigMixin
    """
    
    # 基础服务配置
    service_name: str = Field(default="redfire_service", env="REDFIRE_SERVICE_NAME", description="服务名称")
    service_version: str = Field(default="1.0.0", env="REDFIRE_SERVICE_VERSION", description="服务版本")
    environment: str = Field(default="development", env="REDFIRE_ENVIRONMENT", description="运行环境")
    
    # 【移除】数据库配置 - 不再由框架强制定义
    # 每个服务应该定义自己的数据库配置，例如：
    # - USER_SERVICE_DATABASE_URL
    # - TRADING_SERVICE_PRIMARY_DB_URL
    # - MARKET_DATA_SERVICE_INFLUXDB_URL
    
    # 安全配置
    jwt_secret_key: str = Field(default="dev_jwt_secret_key_32_chars_minimum_length_for_development_only", env="REDFIRE_JWT_SECRET_KEY", description="JWT密钥")
    jwt_algorithm: str = Field(default="HS256", env="REDFIRE_JWT_ALGORITHM", description="JWT算法")
    jwt_expire_minutes: int = Field(default=30, env="REDFIRE_JWT_EXPIRE_MINUTES", description="JWT过期时间(分钟)")
    
    # Redis配置
    redis_url: Optional[str] = Field(default=None, env="REDFIRE_REDIS_URL", description="Redis连接URL")
    redis_pool_size: int = Field(default=10, env="REDFIRE_REDIS_POOL_SIZE", description="Redis连接池大小")
    
    # 日志配置
    log_level: str = Field(default="INFO", env="REDFIRE_LOG_LEVEL", description="日志级别")
    log_format: str = Field(default="json", env="REDFIRE_LOG_FORMAT", description="日志格式")
    
    # 监控配置
    enable_metrics: bool = Field(default=True, env="REDFIRE_ENABLE_METRICS", description="是否启用指标监控")
    metrics_port: int = Field(default=9090, env="REDFIRE_METRICS_PORT", description="指标端口")
    
    # API配置
    api_host: str = Field(default="0.0.0.0", env="REDFIRE_API_HOST", description="API绑定地址")
    api_port: int = Field(default=8000, env="REDFIRE_API_PORT", description="API端口")
    api_workers: int = Field(default=1, env="REDFIRE_API_WORKERS", description="API工作进程数")
    
    @validator('environment')
    def validate_environment(cls, v):
        """验证环境配置"""
        allowed_envs = ['development', 'testing', 'staging', 'production']
        if v not in allowed_envs:
            raise ValueError(f'环境必须是以下之一: {allowed_envs}')
        return v
    
    @validator('log_level')
    def validate_log_level(cls, v):
        """验证日志级别"""
        allowed_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
        if v.upper() not in allowed_levels:
            raise ValueError(f'日志级别必须是以下之一: {allowed_levels}')
        return v.upper()
    
    @validator('jwt_secret_key')
    def validate_jwt_secret_key(cls, v):
        """验证JWT密钥强度"""
        if len(v) < 32:
            raise ValueError('JWT密钥长度至少32个字符')
        return v
    
    @property
    def is_development(self) -> bool:
        """是否为开发环境"""
        return self.environment == 'development'
    
    @property
    def is_production(self) -> bool:
        """是否为生产环境"""
        return self.environment == 'production'
    
    # 【移除】database_config 属性 - 不再由框架提供
    # 每个服务应该实现自己的数据库配置方法
    
    @property
    def security_config(self) -> Dict[str, Any]:
        """获取安全配置字典"""
        return {
            "jwt_secret_key": self.jwt_secret_key,
            "jwt_algorithm": self.jwt_algorithm,
            "jwt_expire_minutes": self.jwt_expire_minutes
        }
    
    class Config:
        env_prefix = "REDFIRE_"
        case_sensitive = False
        # 支持从.env文件加载
        env_file = ".env"
        env_file_encoding = "utf-8"


# ========================================
# 服务数据库配置Mixin类
# ========================================

class ServiceDatabaseConfigMixin:
    """
    服务数据库配置Mixin
    
    为服务提供标准化的数据库配置能力
    每个服务可以继承此Mixin并定义自己的数据库配置
    """
    
    def get_database_configs(self) -> Dict[str, Dict[str, Any]]:
        """
        获取服务的所有数据库配置
        
        子类应该重写此方法，返回服务特定的数据库配置
        
        Returns:
            Dict[str, Dict[str, Any]]: 数据库配置字典
            格式: {
                "primary": {"url": "...", "pool_size": 10},
                "readonly": {"url": "...", "pool_size": 5},
                "timeseries": {"url": "...", "type": "influxdb"}
            }
        """
        raise NotImplementedError("服务必须实现 get_database_configs 方法")
    
    def get_primary_database_config(self) -> Dict[str, Any]:
        """获取主数据库配置"""
        configs = self.get_database_configs()
        if "primary" not in configs:
            raise ValueError("服务必须定义 primary 数据库配置")
        return configs["primary"]
    
    def has_database(self, db_name: str) -> bool:
        """检查是否有指定的数据库配置"""
        return db_name in self.get_database_configs()


class SingleDatabaseServiceMixin(ServiceDatabaseConfigMixin):
    """
    单数据库服务Mixin
    
    适用于只需要一个数据库的简单服务
    """
    
    # 子类需要定义这些字段
    database_url: str
    database_pool_size: int = 10
    database_pool_timeout: int = 30
    database_echo: bool = False
    
    def get_database_configs(self) -> Dict[str, Dict[str, Any]]:
        """返回单一数据库配置"""
        return {
            "primary": {
                "url": self.database_url,
                "pool_size": self.database_pool_size,
                "pool_timeout": self.database_pool_timeout,
                "echo": self.database_echo
            }
        }


class MultiDatabaseServiceMixin(ServiceDatabaseConfigMixin):
    """
    多数据库服务Mixin
    
    适用于需要多个数据库的复杂服务（如读写分离、不同类型数据库等）
    """
    
    def get_database_configs(self) -> Dict[str, Dict[str, Any]]:
        """
        子类需要重写此方法，定义多个数据库配置
        
        示例:
        return {
            "primary": {"url": self.primary_db_url, "pool_size": 20},
            "readonly": {"url": self.readonly_db_url, "pool_size": 10},
            "timeseries": {"url": self.influxdb_url, "type": "influxdb"}
        }
        """
        raise NotImplementedError("多数据库服务必须实现具体的数据库配置")


class DatabaseSettings(BaseSettings):
    """数据库专用配置"""
    
    url: str = Field(..., env="DATABASE_URL")
    pool_size: int = Field(default=10, env="DATABASE_POOL_SIZE")
    pool_timeout: int = Field(default=30, env="DATABASE_POOL_TIMEOUT")
    echo: bool = Field(default=False, env="DATABASE_ECHO")
    
    # 连接池配置
    pool_pre_ping: bool = Field(default=True, env="DATABASE_POOL_PRE_PING")
    pool_recycle: int = Field(default=3600, env="DATABASE_POOL_RECYCLE")
    
    class Config:
        env_prefix = "DATABASE_"


class SecuritySettings(BaseSettings):
    """安全专用配置"""
    
    jwt_secret_key: str = Field(..., env="JWT_SECRET_KEY")
    jwt_algorithm: str = Field(default="HS256", env="JWT_ALGORITHM")
    jwt_expire_minutes: int = Field(default=30, env="JWT_EXPIRE_MINUTES")
    
    # 密码策略
    password_min_length: int = Field(default=8, env="PASSWORD_MIN_LENGTH")
    password_require_uppercase: bool = Field(default=True, env="PASSWORD_REQUIRE_UPPERCASE")
    password_require_numbers: bool = Field(default=True, env="PASSWORD_REQUIRE_NUMBERS")
    password_require_special: bool = Field(default=True, env="PASSWORD_REQUIRE_SPECIAL")
    
    # 会话配置
    session_timeout: int = Field(default=3600, env="SESSION_TIMEOUT")
    max_login_attempts: int = Field(default=5, env="MAX_LOGIN_ATTEMPTS")
    
    class Config:
        env_prefix = "SECURITY_"


class RedisSettings(BaseSettings):
    """Redis专用配置"""
    
    url: str = Field(..., env="REDIS_URL")
    pool_size: int = Field(default=10, env="REDIS_POOL_SIZE")
    timeout: int = Field(default=5, env="REDIS_TIMEOUT")
    
    # 缓存配置
    default_ttl: int = Field(default=3600, env="REDIS_DEFAULT_TTL")
    key_prefix: str = Field(default="redfire:", env="REDIS_KEY_PREFIX")
    
    class Config:
        env_prefix = "REDIS_"


# 便利函数
def load_settings(settings_class: type = RedFireSettings, **kwargs) -> RedFireSettings:
    """
    加载配置的便利函数
    
    Args:
        settings_class: 配置类，默认为RedFireSettings
        **kwargs: 额外的配置参数
        
    Returns:
        配置实例
    """
    return settings_class(**kwargs)


def get_service_settings(service_name: str, **overrides) -> RedFireSettings:
    """
    获取特定服务的配置
    
    Args:
        service_name: 服务名称
        **overrides: 配置覆盖
        
    Returns:
        服务配置实例
    """
    # 设置服务名称环境变量
    os.environ.setdefault("REDFIRE_SERVICE_NAME", service_name)
    
    # 加载配置并应用覆盖
    settings = load_settings()
    
    if overrides:
        # 创建新的配置实例，应用覆盖
        config_dict = settings.dict()
        config_dict.update(overrides)
        settings = RedFireSettings(**config_dict)
    
    return settings


# 配置验证函数
def validate_production_config(settings: RedFireSettings) -> List[str]:
    """
    验证生产环境配置
    
    Args:
        settings: 配置实例
        
    Returns:
        验证错误列表
    """
    errors = []
    
    if settings.is_production:
        # 生产环境必须的安全检查
        if settings.jwt_secret_key == "your-secret-key":
            errors.append("生产环境不能使用默认JWT密钥")
        
        if settings.database_echo:
            errors.append("生产环境不应启用数据库日志")
        
        if settings.log_level == "DEBUG":
            errors.append("生产环境不应使用DEBUG日志级别")
    
    return errors
